package be.kuleuven.cs.mop.domain.model;


import java.util.List;

import be.kuleuven.cs.mop.domain.exceptions.TaskManagerException;
import be.kuleuven.cs.mop.domain.model.impl.InvitationImpl;
import be.kuleuven.cs.mop.domain.model.impl.TaskImpl;
import be.kuleuven.cs.mop.domain.model.impl.UserImpl;



/**
 * The <code>InvitationManager</code> class is responsible
 * for providing/handling information about {@link Invitation}s
 */
public interface InvitationManager {
	
	/**
	 * Accepts the specified {@link Invitation}
	 * 
	 * @param invitation - an {@link InvitationImpl}
	 * @param user - the {@link UserImpl} which is accepting
	 * 
	 * @throws TaskManagerException
	 * 				if the invitation can not be accepted
	 */
	public void accept(InvitationImpl invitation, UserImpl user)
		throws TaskManagerException;
	
	/**
	 * Returns a list of all the existing {@link Invitation}s
	 */
	public List<? extends Invitation> getInvitations();
	
	/**
	 * Returns a list of all the existing {@link Invitation}s
	 * 	for the specified {@link Task}
	 * 
	 * @param task - a {@link Task}
	 */
	public List<? extends Invitation> getInvitations(Task task);
	
	
	/**
	 * Returns a list of all the existing {@link Invitation}s
	 * 	for the specified {@link Task} of the specified {@link UserType}
	 * 
	 * @param task - a {@link Task}
	 * @param type - a {@link UserType}
	 */
	public List<? extends Invitation> getInvitations(Task task, UserType type);
	
	/**
	 * Returns a list of all the existing {@link Invitation}s
	 * 	for the specified {@link User}
	 * 
	 * @param user - a {@link User}
	 */
	public List<? extends Invitation> getInvitations(User user);
	
	/**
	 * Returns a list of all the {@link Task}s
	 * 	to which the specified {@link User} has been invited
	 * 
	 * @param user - a {@link User}
	 */
	public List<TaskImpl> getInvitedTasks(User user);
	
	/**
	 * Returns a list of all the accepted {@link Invitation}s
	 * 	for the specified {@link Task}
	 * 
	 * @param task - a {@link Task}
	 */
	public List<InvitationImpl> getInvitationsAccepted(Task task);
	
	/**
	 * Returns a list of all the accepted {@link Invitation}s
	 * 	for the specified {@link User}
	 * 
	 * @param user - a {@link User}
	 */
	public List<? extends Invitation> getInvitationsAccepted(User user);
	
	/**
	 * Returns a list of all the pending {@link Invitation}s
	 * 	for the specified {@link User}
	 * 
	 * @param user - a {@link User}
	 */
	public List<? extends Invitation> getInvitationsPending(User user);
	
	/**
	 * Creates a new {@link Invitation}
	 * 
	 * @param user - the {@link UserImpl} to be invited
	 * @param task - the appropriate {@link TaskImpl}
	 * 
	 * @throws TaskManagerException
	 * 				if the invitation can't be created
	 */
	public void invite(UserImpl user, TaskImpl task) throws TaskManagerException;
	

	
	/**
	 * Rejects the specified {@link Invitation}
	 * 
	 * @param invitation - an {@link InvitationImpl}
	 * @param user - the {@link UserImpl} which is rejecting
	 * 
	 * @throws TaskManagerException
	 * 				if the invitation can not be rejected
	 */
	public void reject(InvitationImpl invitation, UserImpl user)
		throws TaskManagerException;
	
	/**
	 * Removes the specified {@link Invitation}
	 * 
	 * @param invitation - an {@link InvitationImpl}
	 */
	public void remove(InvitationImpl invitation);
	
	/**
	 * Resets the status of all accepted {@link Invitation}s
	 * 	for the specified {@link Task}
	 * 
	 * @param task - a {@link Task}
	 * 
	 * @throws TaskManagerException
	 * 				if the status of one (or more) {@link Invitation}s
	 * 				can't be changed
	 */
	public void resetAcceptedInvitations(Task task) throws TaskManagerException;
	
		
	
	/**
	 * Removes all invitations of this task.
	 * 
	 * @param task - a {@link Task}
	 */
	public void removeAllInvitationsOfTask(final Task task);
	
}